#include "buffer.h"
Buffer::Buffer(int initBufferSize)
    : buffer_(initBufferSize), readPos_(0), writePos_(0)
{
}
// 缓冲区初始位置的指针
char *Buffer::BeginPtr_()
{
    return &*buffer_.begin(); // 对迭代器的第一个位置进行解引用，然后取地址
}
const char *Buffer::BeginPtr_() const
{
    return &*buffer_.begin();
}
void Buffer::allocateSpace(size_t len) // 缓冲区空间不够时扩容
{
    if (writeableBytes() + readBytes() < len)
    {
        buffer_.resize(writePos_ + len + 1);
    }
    else
    {
        size_t readable = readableBytes();
        std::copy(BeginPtr_() + readPos_, BeginPtr_() + writePos_, BeginPtr_());
        readPos_ = 0;
        writePos_ = readable;
        assert(readable == readableBytes());
    }
}
// 缓存区中可以读取的字节个数
size_t Buffer::readableBytes() const
{
    return writePos_ - readPos_;
}
// 缓冲区中可以写入的字节个数
size_t Buffer::writeableBytes() const
{
    return buffer_.size() - writePos_;
}
// 缓冲区中已经读取的字节数
size_t Buffer::readBytes() const
{
    return readPos_;
}
// 获取当前读指针
const char *Buffer::curReadPtr() const
{
    return BeginPtr_() + readPos_;
}
// 获取当前写指针
const char *Buffer::curWritePtrConst() const
{
    return BeginPtr_() + writePos_;
}
char *Buffer::curWritePtr()
{
    return BeginPtr_() + writePos_;
}
// 更新读指针
void Buffer::updateReadPtr(size_t len)
{
    assert(len <= readableBytes());
    readPos_ += len;
}
void Buffer::updateReadPtrUntilend(const char *end) // 将读指针更新到指定位置
{
    assert(end >= curReadPtr());
    updateReadPtr(end - curReadPtr());
}
// 更新写指针
void Buffer::updateWritePtr(size_t len)
{
    assert(len <= writeableBytes());
    writePos_ += len;
}
// 将写指针和读指针初始化
void Buffer::initPtr()
{
    std::fill(buffer_.begin(), buffer_.end(), 0);
    readPos_ = 0;
    writePos_ = 0;
}

// 保证将数据写入缓冲区
void Buffer::ensureWriteable(size_t len)
{
    if (len > writeableBytes())
    {
        allocateSpace(len);
    }
    assert(writeableBytes() >= len);
}
// 将数据写到缓冲区
void Buffer::append(const char *str, size_t len)
{
    assert(str);
    ensureWriteable(len);
    std::copy(str, str + len, curWritePtr());
    updateWritePtr(len);
}
void Buffer::append(const std::string &str)
{
    append(str.data(), str.length()); // data拿到首地址，length拿到长度不包括\0
}
void Buffer::append(const void *data, size_t len)
{
    assert(data);
    append(static_cast<const char *>(data), len);
}
void Buffer::append(const Buffer &buffer)
{
    append(buffer.curReadPtr(), buffer.readableBytes());
}
// I/O操作的读与写接口
ssize_t Buffer::readFd(int fd, int *Erron)
{
    char buff[65535]; // 暂时的缓冲区
    struct iovec iov[2];
    const size_t writeable = writeableBytes(); // buff对象中可用的空间大小
    iov[0].iov_base = BeginPtr_() + writePos_;
    iov[0].iov_len = writeable;
    iov[1].iov_base = buff;
    iov[1].iov_len = sizeof(buff);
    const ssize_t len = readv(fd, iov, 2);
    if (len < 0)
    {
        // std::cout << "从fd读取数据失败！" << std::endl;
        *Erron = errno;
    }
    else if (static_cast<size_t>(len) <= writeable)
    {
        writePos_ += len;
    }
    else
    {
        writePos_ = buffer_.size(); // 写指针指向末尾
        append(buff, len - writeable);
    }
    return len;
}
ssize_t Buffer::writeFd(int fd, int *Erron)
{
    size_t readSize = readableBytes();
    ssize_t len = write(fd, curReadPtr(), readSize);
    if (len < 0)
    {
        *Erron = errno;
        return len;
    }
    readPos_ += len;
    return len;
}

// 将缓冲区数据转化为字符串
std::string Buffer::AlltoStr()
{
    std::string str(curReadPtr(), readableBytes());
    initPtr();
    return str;
}
